import gugga.events.EventDispatcher;
import mx.utils.Delegate;

import flash.geom.ColorTransform;

import gugga.animations.AnimationSubjectCacheAsBitmapPolicy;
import gugga.animations.IAnimation;
import gugga.animations.PropertiesTweenAnimation;
import gugga.common.EventDescriptor;
import gugga.debug.Assertion;
import gugga.tween.TweensManager;
import gugga.utils.DebugUtils;
import gugga.utils.EventRethrower;
import gugga.utils.Listener;

/**
 * @author stefan
 */
class gugga.animations.ColorTransformTweenAnimation extends EventDispatcher implements IAnimation 
{
	private var mTweenAnimation : PropertiesTweenAnimation;
	
	private var mMovieClip : MovieClip;
	private var mColorTransformObject : ColorTransform;
	
	private var mTweeningProperties : Array = [
		"redMultiplier", "redOffset", 
		"greenMultiplier", "greenOffset", 
		"blueMultiplier", "blueOffset", 
		"alphaMultiplier", "alphaOffset"
	];
	
	public function ColorTransformTweenAnimation ()
	{
		super();
		
		mTweenAnimation = new PropertiesTweenAnimation();
		
		mTweenAnimation.SubjectCacheAsBitmapPolicy = 
			AnimationSubjectCacheAsBitmapPolicy.ForceFalseWhileAnimating;
		
		mTweenAnimation.TweenUpdateDelegate = Delegate.create(this, onTweenUpdated);
		
		mTweenAnimation.addEventListener("completed", Delegate.create(this, onTweenAnimationCompleted));
		
		EventRethrower.create(this, mTweenAnimation, "start");
		EventRethrower.create(this, mTweenAnimation, "interrupted");
	}
	
	private function getTweenToValues(aTransformationMatrix : Array) : Array
	{
		var tweenToValues : Array = new Array();
		tweenToValues[0] = aTransformationMatrix[0] / 100;
		tweenToValues[1] = aTransformationMatrix[1];
		tweenToValues[2] = aTransformationMatrix[2] / 100;
		tweenToValues[3] = aTransformationMatrix[3];
		tweenToValues[4] = aTransformationMatrix[4] / 100;
		tweenToValues[5] = aTransformationMatrix[5];
		tweenToValues[6] = aTransformationMatrix[6] / 100;
		tweenToValues[7] = aTransformationMatrix[7];
		
		return tweenToValues;
	}
	
	public function setTimeTween(
		aMovieClip : MovieClip,  
		aTransformationMatrix : Array, 
		aTweenTime : Number, 
		aEasingEquation : Function) : Void
	{
		Assertion.failIfNull(aMovieClip, "ColorTransformation subject is empty !", this, arguments);
		
		mMovieClip = aMovieClip;
		
		var tweenToValues : Array = getTweenToValues(aTransformationMatrix);
		
		mTweenAnimation.setTimeTween(
			new Object(), // placeholder
			mTweeningProperties,
			tweenToValues,
			aTweenTime,
			aEasingEquation);
	}
	
	public function setFrameTween(
		aMovieClip : MovieClip,  
		aTransformationMatrix : Array, 
		aTweenTime : Number, 
		aEasingEquation : Function) : Void
	{
		Assertion.failIfNull(aMovieClip, "ColorTransformation subject is empty !", this, arguments);
		
		mMovieClip = aMovieClip;
		
		var tweenToValues : Array = getTweenToValues(aTransformationMatrix);
		
		mTweenAnimation.setFrameTween(
			new Object(), // placeholder
			mTweeningProperties,
			tweenToValues,
			aTweenTime,
			aEasingEquation);
	}
	
	private function onTweenUpdated()
	{
		mMovieClip.transform.colorTransform = mColorTransformObject;
	}
	
	private function onTweenAnimationCompleted()
	{
		dispatchEvent({type: "completed", target: this});
	}
	
	public function start() : Void 
	{
		mColorTransformObject = mMovieClip.transform.colorTransform;
		mTweenAnimation.Subject = mColorTransformObject;
		
		mTweenAnimation.start();
	}
	
	public function interrupt() : Void
	{
		mTweenAnimation.interrupt();
	}
	
	public function addCuePoint(aPosition : Number, aEventName : String) : Void 
	{
		mTweenAnimation.addCuePoint(aPosition, aEventName);
		EventRethrower.create(this, mTweenAnimation, aEventName);
	}

	public function isRunning() : Boolean 
	{
		return mTweenAnimation.isRunning();
	}

	public function isImmediatelyInterruptable() : Boolean 
	{
		return mTweenAnimation.isImmediatelyInterruptable();
	}
}